//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package admin_appstore_api_serv

import (
	"context"
	"time"

	"atomgit.com/openlinksaas-org/api-server/admin_api_serv/admin_common"
	"atomgit.com/openlinksaas-org/api-server/dao"
	"atomgit.com/openlinksaas-org/api-server/dao/appstore_dao"
	"atomgit.com/openlinksaas-org/api-server/dao/fs_dao"
	"atomgit.com/openlinksaas-org/proto-gen-go.git/appstore_api"
	"github.com/google/uuid"
	"go.mongodb.org/mongo-driver/mongo"
)

func (apiImpl *AppstoreAdminImpl) AddApp(ctx context.Context, req *appstore_api.AdminAddAppRequest) (*appstore_api.AdminAddAppResponse, error) {
	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &appstore_api.AdminAddAppResponse{
			Code:   appstore_api.AdminAddAppResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	if !sess.AuthOk {
		return &appstore_api.AdminAddAppResponse{
			Code:   appstore_api.AdminAddAppResponse_CODE_NOT_AUTH,
			ErrMsg: "未授权会话",
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.AppStorePerm.AddApp {
		return &appstore_api.AdminAddAppResponse{
			Code:   appstore_api.AdminAddAppResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	if req.MajorCateId != "" {
		exist, err := appstore_dao.CateDao.Exist(ctx, req.MajorCateId, appstore_dao.CATE_LEVEL_MAJOR)
		if err != nil {
			return nil, err
		}
		if !exist {
			return &appstore_api.AdminAddAppResponse{
				Code:   appstore_api.AdminAddAppResponse_CODE_NO_MAJOR_CATE,
				ErrMsg: "一级分类不存在",
			}, nil
		}
	}
	if req.MinorCateId != "" {
		exist, err := appstore_dao.CateDao.Exist(ctx, req.MinorCateId, appstore_dao.CATE_LEVEL_MINOR)
		if err != nil {
			return nil, err
		}
		if !exist {
			return &appstore_api.AdminAddAppResponse{
				Code:   appstore_api.AdminAddAppResponse_CODE_NO_MINOR_CATE,
				ErrMsg: "二级分类不存在",
			}, nil
		}
	}
	if req.SubMinorCateId != "" {
		exist, err := appstore_dao.CateDao.Exist(ctx, req.SubMinorCateId, appstore_dao.CATE_LEVEL_SUB_MINOR)
		if err != nil {
			return nil, err
		}
		if !exist {
			return &appstore_api.AdminAddAppResponse{
				Code:   appstore_api.AdminAddAppResponse_CODE_NO_SUB_MINOR_CATE,
				ErrMsg: "三级分类不存在",
			}, nil
		}
	}

	//检查文件是否存在
	appStoreFsId, err := fs_dao.GlobalFsDao.GetAppStoreFs(ctx)
	if err != nil {
		return nil, err
	}
	exist, err := fs_dao.FsFileDao.Exist(ctx, appStoreFsId, req.FileId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &appstore_api.AdminAddAppResponse{
			Code:   appstore_api.AdminAddAppResponse_CODE_NO_FILE,
			ErrMsg: "应用文件不存在",
		}, nil
	}

	appId := uuid.NewString()
	nowTime := time.Now().UnixNano() / 1e6

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = appstore_dao.AppDao.Insert(sessCtx, &appstore_dao.AppInfoDbItem{
			AppId: appId,
			BaseInfo: appstore_dao.BaseAppInfoDbItem{
				AppName:    req.BaseInfo.AppName,
				AppDesc:    req.BaseInfo.AppDesc,
				IconFileId: req.BaseInfo.IconFileId,
				SrcUrl:     req.BaseInfo.SrcUrl,
				AppType:    uint32(req.BaseInfo.AppType),
			},
			MajorCateId:    req.MajorCateId,
			MinorCateId:    req.MinorCateId,
			SubMinorCateId: req.SubMinorCateId,
			AppPerm: appstore_dao.AppPermDbItem{
				NetPerm: appstore_dao.AppNetPermDbItem{
					CrossDomainHttp: req.AppPerm.NetPerm.CrossDomainHttp,
					ProxyRedis:      req.AppPerm.NetPerm.ProxyRedis,
					ProxyMysql:      req.AppPerm.NetPerm.ProxyMysql,
					ProxyPostGres:   req.AppPerm.NetPerm.ProxyPostGres,
					ProxyMongo:      req.AppPerm.NetPerm.ProxyMongo,
					ProxySsh:        req.AppPerm.NetPerm.ProxySsh,
					NetUtil:         req.AppPerm.NetPerm.NetUtil,
					ProxyGrpc:       req.AppPerm.NetPerm.ProxyGrpc,
				},
				FsPerm: appstore_dao.AppFsPermDbItem{
					ReadFile:  req.AppPerm.FsPerm.ReadFile,
					WriteFile: req.AppPerm.FsPerm.WriteFile,
				},
				ExtraPerm: appstore_dao.AppExtraPermDbItem{
					CrossOriginIsolated: req.AppPerm.ExtraPerm.CrossOriginIsolated,
					OpenBrowser:         req.AppPerm.ExtraPerm.OpenBrowser,
				},
			},
			FileId:       req.FileId,
			OsWindows:    req.OsWindows,
			OsMac:        req.OsMac,
			OsLinux:      req.OsLinux,
			UserApp:      req.UserApp,
			CreateTime:   nowTime,
			UpdateTime:   nowTime,
			InstallCount: 0,
			AgreeCount:   0,
		})
		if err != nil {
			return nil, err
		}
		return &appstore_api.AdminAddAppResponse{
			Code:  appstore_api.AdminAddAppResponse_CODE_OK,
			AppId: appId,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*appstore_api.AdminAddAppResponse), nil
}

func (apiImpl *AppstoreAdminImpl) UpdateApp(ctx context.Context, req *appstore_api.AdminUpdateAppRequest) (*appstore_api.AdminUpdateAppResponse, error) {
	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &appstore_api.AdminUpdateAppResponse{
			Code:   appstore_api.AdminUpdateAppResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	if !sess.AuthOk {
		return &appstore_api.AdminUpdateAppResponse{
			Code:   appstore_api.AdminUpdateAppResponse_CODE_NOT_AUTH,
			ErrMsg: "未授权会话",
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.AppStorePerm.UpdateApp {
		return &appstore_api.AdminUpdateAppResponse{
			Code:   appstore_api.AdminUpdateAppResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := appstore_dao.AppDao.Exist(ctx, req.AppId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &appstore_api.AdminUpdateAppResponse{
			Code:   appstore_api.AdminUpdateAppResponse_CODE_NO_APP,
			ErrMsg: "应用不存在",
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = appstore_dao.AppDao.UpdateBaseInfo(sessCtx, req.AppId, &appstore_dao.BaseAppInfoDbItem{
			AppName:    req.BaseInfo.AppName,
			AppDesc:    req.BaseInfo.AppDesc,
			IconFileId: req.BaseInfo.IconFileId,
			SrcUrl:     req.BaseInfo.SrcUrl,
			AppType:    uint32(req.BaseInfo.AppType),
		})
		if err != nil {
			return nil, err
		}
		return &appstore_api.AdminUpdateAppResponse{
			Code: appstore_api.AdminUpdateAppResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*appstore_api.AdminUpdateAppResponse), nil
}

func (apiImpl *AppstoreAdminImpl) UpdateAppFile(ctx context.Context, req *appstore_api.AdminUpdateAppFileRequest) (*appstore_api.AdminUpdateAppFileResponse, error) {
	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &appstore_api.AdminUpdateAppFileResponse{
			Code:   appstore_api.AdminUpdateAppFileResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	if !sess.AuthOk {
		return &appstore_api.AdminUpdateAppFileResponse{
			Code:   appstore_api.AdminUpdateAppFileResponse_CODE_NOT_AUTH,
			ErrMsg: "未授权会话",
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.AppStorePerm.UpdateApp {
		return &appstore_api.AdminUpdateAppFileResponse{
			Code:   appstore_api.AdminUpdateAppFileResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := appstore_dao.AppDao.Exist(ctx, req.AppId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &appstore_api.AdminUpdateAppFileResponse{
			Code:   appstore_api.AdminUpdateAppFileResponse_CODE_NO_APP,
			ErrMsg: "应用不存在",
		}, nil
	}

	appStoreFsId, err := fs_dao.GlobalFsDao.GetAppStoreFs(ctx)
	if err != nil {
		return nil, err
	}
	exist, err = fs_dao.FsFileDao.Exist(ctx, appStoreFsId, req.FileId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &appstore_api.AdminUpdateAppFileResponse{
			Code:   appstore_api.AdminUpdateAppFileResponse_CODE_NO_FILE,
			ErrMsg: "应用文件不存在",
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = appstore_dao.AppDao.UpdateAppFile(sessCtx, req.AppId, req.FileId)
		if err != nil {
			return nil, err
		}
		return &appstore_api.AdminUpdateAppFileResponse{
			Code: appstore_api.AdminUpdateAppFileResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*appstore_api.AdminUpdateAppFileResponse), nil
}

func (apiImpl *AppstoreAdminImpl) RemoveApp(ctx context.Context, req *appstore_api.AdminRemoveAppRequest) (*appstore_api.AdminRemoveAppResponse, error) {
	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &appstore_api.AdminRemoveAppResponse{
			Code:   appstore_api.AdminRemoveAppResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	if !sess.AuthOk {
		return &appstore_api.AdminRemoveAppResponse{
			Code:   appstore_api.AdminRemoveAppResponse_CODE_NOT_AUTH,
			ErrMsg: "未授权会话",
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.AppStorePerm.RemoveApp {
		return &appstore_api.AdminRemoveAppResponse{
			Code:   appstore_api.AdminRemoveAppResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := appstore_dao.AppDao.Exist(ctx, req.AppId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &appstore_api.AdminRemoveAppResponse{
			Code:   appstore_api.AdminRemoveAppResponse_CODE_NO_APP,
			ErrMsg: "应用不存在",
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = appstore_dao.AppDao.Remove(sessCtx, req.AppId)
		if err != nil {
			return nil, err
		}
		err = appstore_dao.AgreeDao.RemoveByApp(sessCtx, req.AppId)
		if err != nil {
			return nil, err
		}
		return &appstore_api.AdminRemoveAppResponse{
			Code: appstore_api.AdminRemoveAppResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*appstore_api.AdminRemoveAppResponse), nil
}

func (apiImpl *AppstoreAdminImpl) MoveApp(ctx context.Context, req *appstore_api.AdminMoveAppRequest) (*appstore_api.AdminMoveAppResponse, error) {
	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &appstore_api.AdminMoveAppResponse{
			Code:   appstore_api.AdminMoveAppResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	if !sess.AuthOk {
		return &appstore_api.AdminMoveAppResponse{
			Code:   appstore_api.AdminMoveAppResponse_CODE_NOT_AUTH,
			ErrMsg: "未授权会话",
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.AppStorePerm.UpdateApp {
		return &appstore_api.AdminMoveAppResponse{
			Code:   appstore_api.AdminMoveAppResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := appstore_dao.AppDao.Exist(ctx, req.AppId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &appstore_api.AdminMoveAppResponse{
			Code:   appstore_api.AdminMoveAppResponse_CODE_NO_APP,
			ErrMsg: "应用不存在",
		}, nil
	}

	if req.MajorCateId != "" {
		exist, err := appstore_dao.CateDao.Exist(ctx, req.MajorCateId, appstore_dao.CATE_LEVEL_MAJOR)
		if err != nil {
			return nil, err
		}
		if !exist {
			return &appstore_api.AdminMoveAppResponse{
				Code:   appstore_api.AdminMoveAppResponse_CODE_NO_MAJOR_CATE,
				ErrMsg: "一级分类不存在",
			}, nil
		}
	}
	if req.MinorCateId != "" {
		exist, err := appstore_dao.CateDao.Exist(ctx, req.MinorCateId, appstore_dao.CATE_LEVEL_MINOR)
		if err != nil {
			return nil, err
		}
		if !exist {
			return &appstore_api.AdminMoveAppResponse{
				Code:   appstore_api.AdminMoveAppResponse_CODE_NO_MINOR_CATE,
				ErrMsg: "二级分类不存在",
			}, nil
		}
	}
	if req.SubMinorCateId != "" {
		exist, err := appstore_dao.CateDao.Exist(ctx, req.SubMinorCateId, appstore_dao.CATE_LEVEL_SUB_MINOR)
		if err != nil {
			return nil, err
		}
		if !exist {
			return &appstore_api.AdminMoveAppResponse{
				Code:   appstore_api.AdminMoveAppResponse_CODE_NO_SUB_MINOR_CATE,
				ErrMsg: "三级分类不存在",
			}, nil
		}
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = appstore_dao.AppDao.UpdateCate(sessCtx, req.AppId, req.MajorCateId, req.MinorCateId, req.SubMinorCateId)
		if err != nil {
			return nil, err
		}
		return &appstore_api.AdminMoveAppResponse{
			Code: appstore_api.AdminMoveAppResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*appstore_api.AdminMoveAppResponse), nil
}

func (apiImpl *AppstoreAdminImpl) UpdateAppPerm(ctx context.Context, req *appstore_api.AdminUpdateAppPermRequest) (*appstore_api.AdminUpdateAppPermResponse, error) {
	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &appstore_api.AdminUpdateAppPermResponse{
			Code:   appstore_api.AdminUpdateAppPermResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	if !sess.AuthOk {
		return &appstore_api.AdminUpdateAppPermResponse{
			Code:   appstore_api.AdminUpdateAppPermResponse_CODE_NOT_AUTH,
			ErrMsg: "未授权会话",
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.AppStorePerm.UpdateApp {
		return &appstore_api.AdminUpdateAppPermResponse{
			Code:   appstore_api.AdminUpdateAppPermResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := appstore_dao.AppDao.Exist(ctx, req.AppId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &appstore_api.AdminUpdateAppPermResponse{
			Code:   appstore_api.AdminUpdateAppPermResponse_CODE_NO_APP,
			ErrMsg: "应用不存在",
		}, nil
	}
	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = appstore_dao.AppDao.UpdateAppPerm(sessCtx, req.AppId, &appstore_dao.AppPermDbItem{
			NetPerm: appstore_dao.AppNetPermDbItem{
				CrossDomainHttp: req.AppPerm.NetPerm.CrossDomainHttp,
				ProxyRedis:      req.AppPerm.NetPerm.ProxyRedis,
				ProxyMysql:      req.AppPerm.NetPerm.ProxyMysql,
				ProxyPostGres:   req.AppPerm.NetPerm.ProxyPostGres,
				ProxyMongo:      req.AppPerm.NetPerm.ProxyMongo,
				ProxySsh:        req.AppPerm.NetPerm.ProxySsh,
				NetUtil:         req.AppPerm.NetPerm.NetUtil,
				ProxyGrpc:       req.AppPerm.NetPerm.ProxyGrpc,
			},
			FsPerm: appstore_dao.AppFsPermDbItem{
				ReadFile:  req.AppPerm.FsPerm.ReadFile,
				WriteFile: req.AppPerm.FsPerm.WriteFile,
			},
			ExtraPerm: appstore_dao.AppExtraPermDbItem{
				CrossOriginIsolated: req.AppPerm.ExtraPerm.CrossOriginIsolated,
				OpenBrowser:         req.AppPerm.ExtraPerm.OpenBrowser,
			},
		})
		if err != nil {
			return nil, err
		}
		return &appstore_api.AdminUpdateAppPermResponse{
			Code: appstore_api.AdminUpdateAppPermResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*appstore_api.AdminUpdateAppPermResponse), nil
}

func (apiImpl *AppstoreAdminImpl) UpdateAppOs(ctx context.Context, req *appstore_api.AdminUpdateAppOsRequest) (*appstore_api.AdminUpdateAppOsResponse, error) {
	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &appstore_api.AdminUpdateAppOsResponse{
			Code:   appstore_api.AdminUpdateAppOsResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	if !sess.AuthOk {
		return &appstore_api.AdminUpdateAppOsResponse{
			Code:   appstore_api.AdminUpdateAppOsResponse_CODE_NOT_AUTH,
			ErrMsg: "未授权会话",
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.AppStorePerm.UpdateApp {
		return &appstore_api.AdminUpdateAppOsResponse{
			Code:   appstore_api.AdminUpdateAppOsResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := appstore_dao.AppDao.Exist(ctx, req.AppId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &appstore_api.AdminUpdateAppOsResponse{
			Code:   appstore_api.AdminUpdateAppOsResponse_CODE_NO_APP,
			ErrMsg: "应用不存在",
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = appstore_dao.AppDao.UpdateAppOs(sessCtx, req.AppId, req.OsWindows, req.OsMac, req.OsLinux)
		if err != nil {
			return nil, err
		}
		return &appstore_api.AdminUpdateAppOsResponse{
			Code: appstore_api.AdminUpdateAppOsResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*appstore_api.AdminUpdateAppOsResponse), nil
}
